unit Audio;

interface

uses Bass;

type
  TAudio = class(TObject)
  private
    CC: Integer;
    FCount: Integer;
    Channel: array[0..1023] of HSTREAM;
    FVolume: ShortInt;
    procedure SetVolume(Value: ShortInt);
  public
    constructor Create;
    destructor Destroy; override;
    property Volume: ShortInt read FVolume write SetVolume;
    procedure Add(FileName: string; IsLoop: Boolean = False);
    procedure Remove(I: Integer);
    procedure Play(I: Integer = 0);
    procedure Restart(I: Integer);
    procedure Stop(I: Integer); overload;
    procedure Stop; overload;
    procedure Pause;
    procedure Resume;
    function Count: Integer;
  end;

implementation

{ TAudio }

procedure TAudio.Add(FileName: string; IsLoop: Boolean = False);
var
  I: Byte;
begin
  if IsLoop then I := BASS_SAMPLE_LOOP else I := 0;
	Channel[FCount] := BASS_StreamCreateFile(False, PChar(FileName), 0, 0, I);
	if Channel[FCount] <> 0 then Inc(FCount);
end;

function TAudio.Count: Integer;
begin
  Result := FCount
end;

constructor TAudio.Create;
begin
  CC := 0;
  FCount := 0;
  Volume := 100;
  BASS_Init(-1, 44100, BASS_DEVICE_3D, 0, nil);
end;

destructor TAudio.Destroy;
var
  I: Integer;
begin
  if (Count > 0) then
    for I := 0 to Count - 1 do
    	BASS_StreamFree(Channel[I]);
  inherited;
end;

procedure TAudio.Pause;
begin
  BASS_Pause();
end;

procedure TAudio.Play(I: Integer);
begin
  if (I >= 0) then
  begin
    BASS_ChannelSetAttribute(Channel[I], BASS_ATTRIB_VOL, Volume / 100);
    BASS_ChannelPlay(Channel[I], False);
    CC := I;
  end;
end;

procedure TAudio.Remove(I: Integer);
var
	A: Integer;
begin
	if (I >= 0) then
  begin
		BASS_StreamFree(Channel[I]);
		if (I < Count) then
			for A := I to Count - 1 do
				Channel[A] := Channel[A + 1];
		Dec(FCount);
	end;
end;

procedure TAudio.Restart(I: Integer);
begin
  if (I >= 0) then
  begin
    BASS_ChannelSetAttribute(Channel[I], BASS_ATTRIB_VOL, Volume / 100);
    BASS_ChannelPlay(Channel[I], True);
    CC := I;
  end;
end;

procedure TAudio.Resume;
begin
  BASS_Start();
end;

procedure TAudio.SetVolume(Value: ShortInt);
begin
  if (Value > 100) then Value := 100;
  if (Value < 0) then Value := 0;
  FVolume := Value;
  Play(CC);
end;

procedure TAudio.Stop(I: Integer);
begin
  if (I >= 0) then BASS_ChannelStop(Channel[I]);
end;

procedure TAudio.Stop;
var
  I: Integer;
begin
  for I := 0 to Count - 1 do Stop(I);
end;

end.

